package com.douqu.game.main.server.rmi;

import com.douqu.game.core.database.model.PlayerModel;
import com.douqu.game.core.controller.BattleParentController;
import com.douqu.game.core.controller.PlayerController;
import com.douqu.game.core.e.E_BattleResult;
import com.douqu.game.core.e.E_PlayerStatus;
import com.douqu.game.core.entity.Level;
import com.douqu.game.core.entity.battle.BattleControllerInfo;
import com.douqu.game.core.entity.battle.BattleRecord;
import com.douqu.game.core.entity.ext.BattleInfo;
import com.douqu.game.core.entity.sprite.Player;
import com.douqu.game.core.factory.DataFactory;
import com.douqu.game.core.i.IMainServer;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.protobuf.SGInstanceProto;
import com.douqu.game.core.protobuf.SGMainProto;
import com.douqu.game.main.database.mapper.PlayerMapper;
import com.douqu.game.main.msg.InstanceMsgChannel;
import com.douqu.game.main.server.*;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

/**
 * Created by bean on 2017/7/19.
 */
public class ServerManagerImpl extends UnicastRemoteObject implements IMainServer {


    /**
     * 因为UnicastRemoteObject的构造方法抛出了RemoteException异常，因此这里默认的构造方法必须写，必须声明抛出RemoteException异常
     *
     * @throws RemoteException
     */
    public ServerManagerImpl() throws RemoteException {
    }

    @Override
    public void battleStart(int serverId, BattleControllerInfo battleInfo) throws RemoteException
    {
        ServerInfo serverInfo = ServerManager.getInstance().getServerInfo(serverId);
        if(serverInfo != null)
        {
            serverInfo.addBattle(battleInfo);

            WorldManager worldManager = GameServer.getInstance().getWorldManager();
            PlayerController playerController = worldManager.getPlayerController(battleInfo.getTeam1PlayerIndex());
            if(playerController != null)
            {
                playerController.setStatus(E_PlayerStatus.BATTLING);
                playerController.destroy();
            }
            PlayerController targetController = worldManager.getPlayerController(battleInfo.getTeam2PlayerIndex());
            if(targetController != null)
            {
                targetController.setStatus(E_PlayerStatus.BATTLING);
                targetController.destroy();
            }
        }
    }

    @Override
    public void battleEnd(int serverId, BattleControllerInfo battleData)  throws RemoteException
    {
        ServerInfo serverInfo = ServerManager.getInstance().getServerInfo(serverId);
        if(serverInfo != null)
        {
            WorldManager worldManager = GameServer.getInstance().getWorldManager();
            int winTeam = battleData.getWinTeam();

            PlayerController playerController = worldManager.getPlayerController(battleData.getTeam1PlayerIndex());
            if(playerController != null)
            {
                BattleInfo battleInfo = (BattleInfo) playerController.getPlayer().getExtInfo(BattleInfo.class);
                BattleRecord record = new BattleRecord();
                record.setBattleType(battleData.getBattleType());
                record.setId(battleInfo.getRecordCount() + 1);
                record.setName(battleData.getId());
                record.setCreateTime(battleData.getCreateTime());
                record.setStartTime(battleData.getStartTime());
                record.setEndTime(battleData.getEndTime());
                record.setTargetIndex(battleData.getTeam2PlayerIndex());
                if(winTeam == BattleParentController.TEAM_1)
                    record.setResult(E_BattleResult.WIN.getCode());
                else if(winTeam == BattleParentController.TEAM_2)
                    record.setResult(E_BattleResult.LOSE.getCode());
                else
                    record.setResult(E_BattleResult.DOGFALL.getCode());

                battleInfo.addRecord(record);

                playerController.getPlayer().addStar(battleData.getTeam1Star());

                playerController.clearBattle();

                if(battleData.getBattleType() == SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_PVE_INSTANCE_VALUE)
                {
                    //TODO
                    Level level = DataFactory.getInstance().getGameObject(DataFactory.LEVEL_KEY, battleData.getLevelId());
                    byte [] data = SGInstanceProto.C2S_PassLevel.newBuilder()
                            .setMapId(level.getInstanceId())
                            .setLevelId(battleData.getLevelId())
                            .setStarts(battleData.getTeam1Star())
                            .setStarts(2)
                            .build().toByteArray();
                    SpringContext.getMessageChannel(InstanceMsgChannel.class).messageChannel(
                            SGMainProto.E_MSG_ID.MsgID_Instance_PassLevel_VALUE, playerController, data);
                }

            }

            playerController = worldManager.getPlayerController(battleData.getTeam2PlayerIndex());
            if(playerController != null)
            {
                BattleInfo battleInfo = (BattleInfo) playerController.getPlayer().getExtInfo(BattleInfo.class);
                BattleRecord record = new BattleRecord();
                record.setBattleType(battleData.getBattleType());
                record.setId(battleInfo.getRecordCount() + 1);
                record.setName(battleData.getId());
                record.setCreateTime(battleData.getCreateTime());
                record.setStartTime(battleData.getStartTime());
                record.setEndTime(battleData.getEndTime());
                record.setTargetIndex(battleData.getTeam1PlayerIndex());
                if(winTeam == BattleParentController.TEAM_2)
                    record.setResult(E_BattleResult.WIN.getCode());
                else if(winTeam == BattleParentController.TEAM_1)
                    record.setResult(E_BattleResult.LOSE.getCode());
                else
                    record.setResult(E_BattleResult.DOGFALL.getCode());

                battleInfo.addRecord(record);

                playerController.getPlayer().addStar(battleData.getTeam2Star());

                playerController.clearBattle();
            }

            serverInfo.removeBattle(battleData);
        }
    }

    @Override
    public void battleOffline(int serverId, String playerIndex)  throws RemoteException {
        PlayerController playerController = GameServer.getInstance().getWorldManager().getPlayerController(playerIndex);
        if(playerController != null)
        {
            playerController.setStatus(E_PlayerStatus.BATTLE_OFFLINE);
        }
    }

    @Override
    public void updateStatus(int serverId, String playerIndex, String status) throws RemoteException {
        PlayerController playerController = GameServer.getInstance().getWorldManager().getPlayerController(playerIndex);
        if(playerController != null)
        {
            playerController.setStatus(E_PlayerStatus.valueOf(status));
        }
    }


    @Override
    public Player getOnlinePlayer(String playerIndex)  throws RemoteException
    {
        PlayerController playerController = GameServer.getInstance().getWorldManager().getPlayerController(playerIndex);
        if(playerController != null)
        {
            return playerController.getPlayer();
        }

        return null;
    }

    @Override
    public Player getOfflinePlayer(String playerIndex)  throws RemoteException
    {
        PlayerMapper playerMapper = SpringContext.getBean(PlayerMapper.class);
        PlayerModel playerModel = playerMapper.getPlayerByIndex(playerIndex);
        if(playerModel != null)
        {
            Player player = new Player(GameServer.getInstance().getWorldManager().getWorldInfo());
            player.load(playerModel);

            return player;
        }
        return null;
    }

    @Override
    public DataFactory getDataFactory() throws RemoteException
    {
        return DataFactory.getInstance();
    }
}
